#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ls (x << 1)
#define rs (x << 1 | 1)
using namespace std;

const int N = 4e4 + 10, INF = 0x3f3f3f3f;

int n, m, root = 1;
vector<pair<int, int>> g[N];
void add(int x, int y, int w) { g[x].push_back({ y,w }); g[y].push_back({ x,w }); }

int fa[N], dep[N], siz[N], son[N], dis[N];
int top[N], dfn[N], seg[N];

struct node { int l, r, v, lazy; }tr[N << 2];
void pushup(int x) { tr[x].v = min(tr[ls].v, tr[rs].v); }
void pushdown(int x) {
    if (tr[x].lazy != 0) {
        tr[ls].lazy += tr[x].lazy;
        tr[rs].lazy += tr[x].lazy;
        tr[ls].v += tr[x].lazy;
        tr[rs].v += tr[x].lazy;
        tr[x].lazy = 0;
    }
}
void build(int x, int l, int r)
{
    tr[x].l = l, tr[x].r = r;
    tr[x].v = tr[x].lazy = 0;
    if (l == r) {
        tr[x].v = dis[seg[l]];
        return;
    }
    int mid = (l + r) >> 1;
    build(ls, l, mid);build(rs, mid + 1, r);
    pushup(x);
}

void modify(int x, int l, int r, int d)
{
    if (l <= tr[x].l && tr[x].r <= r) {
        tr[x].v += d;tr[x].lazy += d;
        return;
    }
    pushdown(x);
    int mid = (tr[x].l + tr[x].r) >> 1;
    if (l <= mid) modify(ls, l, r, d);
    if (r > mid) modify(rs, l, r, d);
    pushup(x);
}

int query(int x, int l, int r)
{
    if (l <= tr[x].l && tr[x].r <= r) return tr[x].v;
    pushdown(x);
    int mid = (tr[x].l + tr[x].r) >> 1, res = INF;
    if (l <= mid) res = min(res, query(ls, l, r));
    if (r > mid) res = min(res, query(rs, l, r));
    return res;
}

void dfs1(int x, int f)
{
    fa[x] = f;
    dep[x] = dep[f] + 1;
    siz[x] = 1;
    son[x] = 0;
    int max_son = -1;
    for (auto& [y, w] : g[x]) {
        if (y == f) continue;
        dis[y] = w;
        dfs1(y, x);
        siz[x] += siz[y];
        if (max_son < siz[y]) son[x] = y, max_son = siz[y];
    }
}

int cntd = 0;
void dfs2(int x, int t)
{
    top[x] = t;
    dfn[x] = ++cntd;
    seg[cntd] = x;
    if (son[x] == 0) return;
    dfs2(son[x], t);
    for (auto& [y, w] : g[x]) {
        if (y == fa[x] || y == son[x]) continue;
        dfs2(y, y);
    }
}

void add_range(int x, int y, int d)
{
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) swap(x, y);
        modify(1, dfn[top[x]], dfn[x], d);
        x = fa[top[x]];
    }
    if (dep[x] > dep[y]) swap(x, y);
    if (x != y) modify(1, dfn[x] + 1, dfn[y], d);
}

int query_range(int x, int y)
{
    int res = INF;
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) swap(x, y);
        res = min(res, query(1, dfn[top[x]], dfn[x]));
        x = fa[top[x]];
    }
    if (dep[x] > dep[y]) swap(x, y);
    if (x != y) res = min(res, query(1, dfn[x] + 1, dfn[y]));
    return res;
}

void solve()
{
    while (cin >> n >> m) {
        for (int i = 1;i <= n;i++) g[i].clear();
        for (int i = 1;i < n;i++) {
            int x, y, w;cin >> x >> y >> w;
            add(x, y, w);
        }
        dfs1(1, 0);
        cntd = 0;dfs2(1, 1);
        build(1, 1, n);

        int ans = 0;
        while (m--) {
            int a, b, c;cin >> a >> b >> c;
            int mi = query_range(a, b);
            if (c <= mi) {
                add_range(a, b, -c);
                ans += c;
            }
        }
        cout << ans << '\n';
    }
}

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
#define ONLINE_JUDGE
#ifndef ONLINE_JUDGE
    std::istringstream in(R"()");
    std::cin.rdbuf(in.rdbuf());
#endif
    int T = 1;
    //cin>>T;
    for (int i = 1;i <= T;i++) {
        solve();
    }
}